package com.smartcampusbackend.controller;

import com.smartcampusbackend.model.Course;
import com.smartcampusbackend.model.LeaveApplication;
import com.smartcampusbackend.model.OperationLog;
import com.smartcampusbackend.service.CourseService;
import com.smartcampusbackend.service.LeaveApplicationService;
import com.smartcampusbackend.service.OperationLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.util.HashMap;
import com.smartcampusbackend.mapper.UserMapper;
import com.smartcampusbackend.model.User;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.smartcampusbackend.mapper.LeaveApplicationMapper;
import com.smartcampusbackend.mapper.GraduationApplicationMapper;
import com.smartcampusbackend.mapper.TitleApplicationMapper;
import java.util.ArrayList;
import com.smartcampusbackend.model.GraduationApplication;
import com.smartcampusbackend.model.TitleApplication;

@RestController
@RequestMapping("/api")
public class LeaveApplicationController {
    @Autowired
    private LeaveApplicationService leaveApplicationService;
    
    @Autowired
    private CourseService courseService;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LeaveApplicationMapper leaveApplicationMapper;

    @Autowired
    private GraduationApplicationMapper graduationApplicationMapper;

    @Autowired
    private TitleApplicationMapper titleApplicationMapper;

    // 学生提交请假申请
    @PostMapping("/leave-application")
    public ResponseEntity<?> submitLeaveApplication(@RequestBody LeaveApplication application) {
        // 安全检查：再次验证请假时长
        boolean isLongTerm = leaveApplicationService.isLongTermLeave(
            application.getStartDate(), application.getEndDate());
        
        if (isLongTerm) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "请假时长超出3天，需要开具纸质证明，不可通过线上办理");
            return ResponseEntity.ok(response);
        }
        
        boolean result = leaveApplicationService.submitLeaveApplication(application);
        if (result) {
            String operatorName = "";
            if (application.getStudentId() != null) {
                User user = userMapper.selectById(application.getStudentId());
                if (user != null && user.getUsername() != null) {
                    operatorName = user.getUsername();
                }
            }
            if (operatorName.isEmpty() && application.getStudentId() != null) {
                operatorName = application.getStudentId().toString();
            }
            OperationLog log = new OperationLog();
            log.setBusinessType("请假");
            log.setBusinessId(application.getId() != null ? application.getId().toString() : "");
            log.setOperationType("提交");
            log.setOperatorId(application.getStudentId() != null ? application.getStudentId().toString() : "");
            log.setOperatorName(operatorName);
            log.setOperatorRole("学生");
            log.setContent(operatorName + "提交了请假申请");
            log.setStatus("待审批");
            log.setIsSignature(false);
            log.setCreateTime(java.util.Date.from(ZonedDateTime.now(ZoneId.of("Asia/Shanghai")).toInstant()));
            operationLogService.addLog(log);
        }
        return ResponseEntity.ok(Map.of("success", result));
    }

    // 教师或管理员审批请假申请
    @PostMapping("/admin/leave-applications/{applicationId}/approve")
    public ResponseEntity<?> approveLeaveApplication(
            @PathVariable Long applicationId, 
            @RequestBody Map<String, Object> request) {
        boolean approved = (boolean) request.get("approved");
        String rejectReason = request.get("rejectReason") != null ? (String) request.get("rejectReason") : null;
        boolean result = leaveApplicationService.approveLeaveApplication(applicationId, approved, rejectReason);
        if (result) {
            String adminId = request.get("adminId") != null ? request.get("adminId").toString() : "";
            String adminName = "";
            if (!adminId.isEmpty()) {
                User user = userMapper.selectById(adminId);
                if (user != null && user.getUsername() != null) {
                    adminName = user.getUsername();
                }
            }
            if (adminName.isEmpty() && !adminId.isEmpty()) {
                adminName = adminId;
            }
            String content = adminName + (approved ? "审批通过了请假申请" : "审批拒绝了请假申请");
            if (rejectReason != null) content += "，原因：" + rejectReason;
            OperationLog log = new OperationLog();
            log.setBusinessType("请假");
            log.setBusinessId(applicationId.toString());
            log.setOperationType("审批");
            log.setOperatorId(adminId);
            log.setOperatorName(adminName);
            log.setOperatorRole("管理员");
            log.setContent(content);
            log.setStatus("已签章");
            log.setIsSignature(true);
            log.setCreateTime(java.util.Date.from(ZonedDateTime.now(ZoneId.of("Asia/Shanghai")).toInstant()));
            operationLogService.addLog(log);
        }
        return ResponseEntity.ok(Map.of("success", result));
    }

    // 获取学生的请假申请记录
    @GetMapping("/users/me/leave-applications")
    public ResponseEntity<List<LeaveApplication>> listStudentLeaveApplications(@RequestParam Long studentId) {
        List<LeaveApplication> applications = leaveApplicationService.listStudentLeaveApplications(studentId);
        return ResponseEntity.ok(applications);
    }
    
    // 获取教师课程的请假申请
    @GetMapping("/teacher/leave-applications")
    public ResponseEntity<List<Map<String, Object>>> listTeacherLeaveApplications(@RequestParam String teacherId) {
        List<Map<String, Object>> applications = leaveApplicationService.listLeaveApplicationsForTeacher(teacherId);
        return ResponseEntity.ok(applications);
    }
    
    // 管理员获取所有请假申请
    @GetMapping("/admin/leave-applications")
    public ResponseEntity<List<Map<String, Object>>> listAllLeaveApplications() {
        List<Map<String, Object>> applications = leaveApplicationService.listAllLeaveApplications();
        return ResponseEntity.ok(applications);
    }
    
    // 检查请假时长
    @GetMapping("/leave-application/check-duration")
    public ResponseEntity<?> checkLeaveDuration(
            @RequestParam String startDate,
            @RequestParam String endDate) {
        try {
            // 使用更健壮的日期解析方式
            LocalDateTime start;
            LocalDateTime end;
            
            try {
                // 尝试直接解析ISO格式
                start = LocalDateTime.parse(startDate);
                end = LocalDateTime.parse(endDate);
            } catch (Exception e) {
                // 失败时尝试从ISO日期时间字符串转换
                DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
                try {
                    start = LocalDateTime.parse(startDate, formatter);
                    end = LocalDateTime.parse(endDate, formatter);
                } catch (Exception e2) {
                    // 最后尝试从ISO Instant转换
                    start = LocalDateTime.ofInstant(
                        java.time.Instant.parse(startDate),
                        ZoneId.of("Asia/Shanghai")
                    );
                    end = LocalDateTime.ofInstant(
                        java.time.Instant.parse(endDate),
                        ZoneId.of("Asia/Shanghai")
                    );
                }
            }
            
            boolean isLongTerm = leaveApplicationService.isLongTermLeave(start, end);
            
            Map<String, Object> response = new HashMap<>();
            response.put("isLongTerm", isLongTerm);
            if (isLongTerm) {
                response.put("message", "请假时长超过3天，需要开具纸质证明，不可通过线上办理");
            } else {
                // 计算具体天数供前端显示
                long days = java.time.temporal.ChronoUnit.DAYS.between(start.toLocalDate(), end.toLocalDate());
                long hours = java.time.temporal.ChronoUnit.HOURS.between(start, end);
                response.put("days", days);
                response.put("hours", hours);
                response.put("message", "当前请假时长符合要求，可以线上申请");
            }
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, String> errorResponse = new HashMap<>();
            errorResponse.put("error", e.getMessage());
            errorResponse.put("details", "日期格式错误或参数无效: " + e.toString());
            return ResponseEntity.badRequest().body(errorResponse);
        }
    }
    
    // 获取学生已选课程（用于请假申请选择）
    @GetMapping("/student/{studentId}/courses")
    public ResponseEntity<List<Course>> getStudentCourses(@PathVariable Long studentId) {
        List<Course> courses = courseService.listSelectedCourses(studentId.toString());
        return ResponseEntity.ok(courses);
    }

    @GetMapping("/admin/todo")
    public List<Map<String, Object>> getAllPendingTodos() {
        LocalDateTime threeMinutesAgo = LocalDateTime.now().minusMinutes(3);
        List<Map<String, Object>> todos = new ArrayList<>();
        // 请假申请
        List<LeaveApplication> leaveList = leaveApplicationMapper.selectList(
            new QueryWrapper<LeaveApplication>()
                .eq("status", "PENDING")
                .le("create_time", threeMinutesAgo)
        );
        for (LeaveApplication leave : leaveList) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", leave.getId());
            item.put("type", "LEAVE");
            item.put("applicantId", leave.getStudentId());
            item.put("createTime", leave.getCreateTime());
            todos.add(item);
        }
        // 毕业申请
        List<GraduationApplication> gradList = graduationApplicationMapper.selectList(
            new QueryWrapper<GraduationApplication>()
                .eq("status", "PENDING")
                .le("application_date", threeMinutesAgo)
        );
        for (GraduationApplication grad : gradList) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", grad.getId());
            item.put("type", "GRADUATION");
            item.put("applicantId", grad.getStudentId());
            item.put("createTime", grad.getApplicationDate());
            todos.add(item);
        }
        // 职称申请
        List<TitleApplication> titleList = titleApplicationMapper.selectList(
            new QueryWrapper<TitleApplication>()
                .eq("status", "PENDING")
                .le("create_time", threeMinutesAgo)
        );
        for (TitleApplication title : titleList) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", title.getId());
            item.put("type", "TITLE");
            item.put("applicantId", title.getTeacherId());
            item.put("createTime", title.getCreateTime());
            todos.add(item);
        }
        return todos;
    }
} 